﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Text;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using ZJGIS.EngineControl;
using ZJGIS.Report.model;
using ZJGIS.Framework;
using ZJGIS.ADF.BaseClasses;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;

namespace ZJGIS.Report.button
{
    internal class WaterStatButton : BaseDrawPolygonTool
    {
        private IElement m_pElement;
        private StatisticReport m_pReport;
        private IFeatureLayer pFeatureLayer;
        private string strID = "水系面";
        private StatLayer m_pStatLyr = null;
        private DataTable m_pTable = null;
        IApplication m_Application = null;
        IMapControl3 pMapControl = null;

        public WaterStatButton()
        {
            base.m_caption = "水系统计";
            base.m_toolTip = base.m_caption;
        }

        public override void OnCreate(object hook)
        {
            m_Application = hook as IApplication;
            base.OnCreate(hook);
        }

        public override bool Enabled
        {
            get
            {
                
                if ((m_Application as IFramework).IsMapCtrlactive)
                {
                    IEnumLayer layers = (m_Application.Document as IMxDocument).ActiveView.FocusMap.get_Layers(null, true);
                    ILayer layer = layers.Next();
                    while (layer != null)
                    {
                        if (layer is IFeatureLayer)
                        {
                            Marshal.ReleaseComObject(layers);
                            return true;
                        }
                        layer = layers.Next();
                    }
                    Marshal.ReleaseComObject(layers);
                }
                return false;
            }
        }

        public override void OnClick()
        {
            //if ((m_Application as IFramework).Tool == this) return;
            base.OnClick();

            if ((m_Application as IFramework).IsMapCtrlactive)
                pMapControl = (m_Application as IFramework).MapControl;
            else
                return;

            if (pMapControl == null || pMapControl.Map.LayerCount == 0) return;

            m_pStatLyr = StatFactory.GetLayerByID(strID);
            if (m_pStatLyr == null)
            {
                ControlUtility.ShowInfomationMsgbox("尚未找到水系面层,请加载水系面层！");
                return;
            }
            pFeatureLayer = CartoUtility.FindFeatureLayerByName(pMapControl.Map, m_pStatLyr.Value);
            if (pFeatureLayer == null)
            {
                ControlUtility.ShowInfomationMsgbox("尚未找到水系面层,请加载水系面层！");
                return;
            }
            m_cursor = Cursors.Cross;
        }

        public override int Bitmap
        {
            get
            {
                string bitmapResourceName = "ZJGIS.Report.Res." + this.GetType().Name + ".png";
                System.IO.Stream s = GetType().Assembly.GetManifestResourceStream(bitmapResourceName);
                if (s == null) return 0;
                return new Bitmap(s).GetHbitmap().ToInt32(); 
            }
        }

        public override void OnDblClick()
        {

            base.OnDblClick();
            if (pFeatureLayer == null) { return; }
            if (pMapControl == null) { return; }
            if (m_geom == null || m_geom.IsEmpty) { return; }
            if (m_pTable == null)
            {
                m_pTable = CreateWaterDatatable();
            }
            else if (m_pTable.Rows.Count > 0)
            {
                m_pTable.Rows.Clear();
            }

            IPolygon pPolygon = m_geom as IPolygon;
            ITopologicalOperator2 pTopo = pPolygon as ITopologicalOperator2;
            pTopo.IsKnownSimple_2 = false;
            pTopo.Simplify();
            pTopo.IsKnownSimple_2 = true;
            pPolygon.Project(((IGeoDataset)pFeatureLayer.FeatureClass).SpatialReference );

            Application.DoEvents();
            ISpatialFilter pSF = new SpatialFilterClass();
            pSF.Geometry = pPolygon;
            pSF.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            pSF.WhereClause = m_pStatLyr.WhereClause();
            IFeatureCursor pFeatureCursor = pFeatureLayer.FeatureClass.Search(pSF, false);
            IFeature pFeature = pFeatureCursor.NextFeature();
            while (pFeature != null)
            {
                AddDatarow(m_pTable, pFeature, m_geom);
                pFeature = pFeatureCursor.NextFeature();
            }
            if (m_pTable.Rows.Count == 0)
            {
                ControlUtility.ShowInfomationMsgbox("尚未检索到水系面要素，请重试！");
                pMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
                return;
            }
            if (m_pReport == null || m_pReport.IsDisposed)
            {
                m_pReport = new StatisticReport();
            }

            m_pReport.AddConnectDatatable = m_pTable;
            m_pReport.ReportName = "水系统计报表.rpt";

            if (!m_pReport.Visible) m_pReport.Show((m_Application as IFramework).MdiForm);
            m_pReport.RefreshReport();

        }


        private  DataTable CreateWaterDatatable()
        {
            DataTable pTable = new DataTable();

            foreach (ReportField  field in m_pStatLyr.ReportFields )
            {
                DataColumn pColumn = new DataColumn(field.Key);
                pColumn.DataType =Type.GetType("System."+field.Type);
                if (field.Type.ToLower().Contains("int"))
                {
                    pColumn.DefaultValue = 0;
                }
                else if (field.Type.ToLower().Contains("double"))
                {
                    pColumn.DefaultValue = 0.00;
                }
                pTable.Columns.Add(pColumn);
            }

            return pTable;
        }

        private  void AddDatarow(DataTable pTable, IFeature pFeature, IGeometry pGeo)
        {
            if (pFeature == null || pTable == null) { return; }
            DataRow pRow = pTable.NewRow();
            IFields PFields = pFeature.Fields;
            int idx =-1;
            foreach (ReportField  field in m_pStatLyr.ReportFields )
            {
                switch (field.Key)
                {
                    case "OID":
                        pRow[field.Key] = pFeature.OID.ToString();
                        break;
                    case "FCODE":
                        idx = pFeature.Fields.FindField(field.Value );
                        if (idx > -1)
                        {
                            pRow[field.Key] = pFeature.get_Value(idx).ToString();
                            if (m_pStatLyr.StatCodes.Count > 0)
                            {
                                string strType = GetWaterType(pFeature.get_Value(idx).ToString());
                                pRow["TYPE"]=strType==null?"" :strType;
                            }
                        }
                        break;
                    case "NAME":
                        idx = pFeature.Fields.FindField(field.Value );
                        if (idx > -1)
                        {
                            if (pFeature.get_Value(idx) == null || Convert.IsDBNull(pFeature.get_Value(idx)))
                            {
                                pRow[field.Key] = "";
                            }
                            else
                            {
                                pRow[field.Key] = pFeature.get_Value(idx).ToString();
                            }
                        }
                        break;
                    case "FULLAREA":
                        IPolygon pPolygon = pFeature.ShapeCopy as IPolygon;
                        IArea pArea=pPolygon as IArea;
                        pRow[field.Key] = Math.Abs(pArea.Area);
                        ITopologicalOperator pTopo=pGeo as ITopologicalOperator;
                        IGeometry pIntersectGeo=null;
                        try
                        {
                            pIntersectGeo=pTopo.Intersect(pPolygon,esriGeometryDimension.esriGeometry2Dimension);
                            if(pIntersectGeo !=null ||!pIntersectGeo.IsEmpty )
                            {
                                pArea =pIntersectGeo as IArea;
                                pRow["AREA"]=Math.Abs(pArea.Area);
                            }
                        }
                        catch(Exception ce)
                        {
                            pIntersectGeo=null;
                        }

                        break;
                    default:
                        break;
                }
            }

            pTable.Rows.Add(pRow);
        }

        private string GetWaterType(string strCode)
        {
            if (strCode == null || strCode.Length == 0 || m_pStatLyr.StatCodes.Count == 0)
            {
                return null;
            }
            for (int i = 0; i < m_pStatLyr.StatCodes.Count; i++)
            {
                if (m_pStatLyr.StatCodes[i].Fcode == strCode)
                {
                    return m_pStatLyr.StatCodes[i].Value;
                }
            }
            return null;
        }


    }
}
